from django.shortcuts import render

# Create your views here.
from django.shortcuts import render, HttpResponse
from django.template import loader, RequestContext
from django.template.context import Context
from ImageTest import models as md
from django.core.cache import cache
# Create your views here.
from PIL import Image
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="static/file/msyh.ttc", size=12)
plt.rcParams['axes.unicode_minus'] = False   # 步骤二（解决坐标轴负数的负号显示问题）
import json
import numpy as np

import torch
import torch.nn.functional as F
from torchvision import models, transforms

# 1.下载并加载预训练模型
model = models.resnet18(pretrained=True)
model = model.eval()

# 2.加载标签并对输入数据进行处理
labels_path = 'static/file/imagenet_class_index.json'
with open(labels_path) as json_data:
    idx2labels = json.load(json_data)
# print(idx2labels)


def getone(onestr):
    return onestr.replace(',', ' ')


# 加载中文标签
with open('static/file/zh_label.csv', 'r+', encoding='GBK') as f:
    # print(f)
    # print(map(getone, list(f)))
    zh_labels = list(map(getone, list(f)))


transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225]
    )
])

# 3.使用模型进行预测
def preimg(img):
    if img.mode == 'RGBA':
        ch = 4
        a = np.asarray(img)[:, :, :3]
        img = Image.fromarray(a)
    return img

def updateinfo(request):
    if request.method == 'POST':
        ph = request.FILES.get('photo')
        if ph is None or 'image' not in ph.content_type:  # 如果未上传或上传非图片
            return render(request, 'upload.html')
        name = ph.name,  # 拿到图片的名字
        name = name[0]
        if not cache.get(name):
            try:
                photo = md.mypicture.objects.get(name=name)
                path = photo.path
                return render(request, "upload.html", {'path': path})
            except:
                # img = request.FILES.get('photo')
                # user = request.FILES.get('photo').name
                im = Image.open(ph)
                transformed_img = transform(im)

                inputimg = transformed_img.unsqueeze(0)

                output = model(inputimg)
                output = F.softmax(output, dim=1)

                prediction_score, pred_label_idx = torch.topk(output, 3)
                prediction_score = prediction_score.detach().numpy()[0]

                pred_label_idx = pred_label_idx.detach().numpy()[0]
                predicted_label = idx2labels[str(pred_label_idx[0])][1]
                predicted_label_zh = zh_labels[pred_label_idx[0]]

                # 4.预测结果可视化
                fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 8))
                fig.sca(ax1)
                ax1.imshow(im)
                plt.xticks([])
                plt.yticks([])

                barlist = ax2.bar(range(3), [i for i in prediction_score])
                barlist[0].set_color('g')

                plt.sca(ax2)
                plt.ylim([0, 1.1])

                plt.xticks(range(3),
                           # [idx2labels[str(i)][1] for i in pred_label_idx],
                           [zh_labels[pred_label_idx[i]] for i in range(3)],
                           rotation=30,
                           fontproperties=font)
                fig.subplots_adjust(bottom=0.2)
                filename = 'static/media/photos/recog-' + name
                plt.savefig(filename)
                new_img = md.mypicture(
                    name=name,  # 拿到图片的名字
                    path=filename,  # 拿到图片
                )
                cache.set(name, filename, timeout=60)  # 时间限制1分钟
                new_img.save()  # 保存图片
                path = filename
                return render(request, "upload.html", {'path': path})
        else:
            path = cache.get(name)
            return render(request, "upload.html", {'path': path})
    return render(request, 'upload.html')
